package net.airtheva.uniqueTask5;

import java.util.ArrayList;
import java.util.HashMap;

import net.airtheva.uniqueTask5.utils.Utils;
import net.airtheva.weather.Constants;
import net.airtheva.weather.Location;
import net.airtheva.weather.Weather;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.example.android.swipedismiss.SwipeDismissListViewTouchListener;

public class WeatherActivity extends FragmentActivity {

	public static final String TAG = "WeatherActivity";
	
	public static final String KEY_WEATHER_ICON = "weatherIcon";
	public static final String KEY_LOCAITON_NAME = "locationName";
	public static final String KEY_WEATHER = "weather";
	public static final String KEY_TEMPERATURE = "temperature";

	class RefreshWeathersAsyncTask extends AsyncTask<Location, Integer, Void> {

		@Override
		protected void onPreExecute() {
			setProgressBarIndeterminateVisibility(true);
			mProgressBar.setVisibility(View.VISIBLE);
		}

		@Override
		protected Void doInBackground(Location... params) {

				for (int i = 0; i < params.length; i++) {

					publishProgress(params.length, i + 1);

					Location location = params[i];
					
					mWeatherService.RefreshWeather(location);

				}

			return null;

		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			UpdateLocationsData();
			SetSummaryData(mLocationsData);
			mProgressBar.setMax(values[0]);
			mProgressBar.setProgress(values[1]);
		}

		@Override
		protected void onPostExecute(Void result) {
			mProgressBar.setVisibility(View.INVISIBLE);
			setProgressBarIndeterminateVisibility(false);

			UpdateLocationsData();
			SetSummaryData(mLocationsData);
			ShowLocationDetail(mDetailedLocation);
		}
		
	}

	ServiceConnection mServiceConnection;
	WeatherService mWeatherService;
	
	Location mDetailedLocation;
	
	ArrayList<HashMap<String, Object>> mLocationsData;

	DrawerLayout mDrawerLayout;
	
	ProgressBar mProgressBar;
	
	TextView mCurrentTemperature;
	
	TextView mLocationName;
	
	ListView mDetail;
	
	Button mLocate;
	OverScrollListView mSummary;
	Button mAddLocation;

	ActionBarDrawerToggle mDrawerToggle;

	Sensor mTemperatureSensor;
	SensorEventListener mTemperatureSensorListener;
	
	Handler mHandler;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

		mServiceConnection = new ServiceConnection() {
			
			@Override
			public void onServiceConnected(ComponentName name, IBinder service) {
				
				mWeatherService = ((WeatherService._Binder) service).GetServive();
				
				mDetailedLocation = mWeatherService.CurrentLocation;
				
				LoadLocations();
				
				mHandler.postDelayed(new Runnable() {
					@Override
					public void run() {
						//UpdateCurrentLocation();
						
						RefreshWeathers();
					}
				}, 3000);

			}
			
			@Override
			public void onServiceDisconnected(ComponentName name) {
				
			}
			
		};
		
		mLocationsData = new ArrayList<HashMap<String, Object>>();

		setContentView(R.layout.activity_weather);

		getActionBar().setDisplayHomeAsUpEnabled(true);
		getActionBar().setHomeButtonEnabled(true);

		mDrawerLayout = (DrawerLayout) findViewById(R.id.activity_weather);
		mDrawerLayout.setOnKeyListener(new View.OnKeyListener() {
			@Override
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				// TODO Auto-generated method stub
				switch(keyCode) {
				case KeyEvent.KEYCODE_BACK:
					if(mDrawerLayout.isDrawerOpen(GravityCompat.START)) {
						CloseDrawer();
						return true;
					}
					return false;
				default:
					return false;
				}
			}
		});
		mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer, R.string.app_name, R.string.app_name) {

			@Override
			public void onDrawerClosed(View drawerView) {
				// TODO Auto-generated method stub
				super.onDrawerClosed(drawerView);
				mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
			}

			@Override
			public void onDrawerOpened(View drawerView) {
				// TODO Auto-generated method stub
				super.onDrawerOpened(drawerView);
				mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
			}

		};
		mDrawerLayout.setDrawerListener(mDrawerToggle);

		mProgressBar = (ProgressBar) findViewById(R.id.activity_weather_progressBar);
		
		mCurrentTemperature = (TextView) findViewById(R.id.activity_weather_currentTemperature);
		
		mLocationName = (TextView) findViewById(R.id.activity_weather_locationName);
		
		mDetail = (ListView) findViewById(R.id.activity_weather_detail);
		
		mLocate = (Button) findViewById(R.id.activity_weather_locate);
		mLocate.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				UpdateCurrentLocation();
				
			}
		});

		mSummary = (OverScrollListView) findViewById(R.id.activity_weather_summary);
		// 滑动删除。
		SwipeDismissListViewTouchListener touchListener = new SwipeDismissListViewTouchListener(mSummary, new SwipeDismissListViewTouchListener.DismissCallbacks() {
			@Override
			public boolean canDismiss(int position) {
				if(position == 0) {
					return false;
				}
				else {
					return true;
				}
			}

			@Override
			public void onDismiss(ListView listView, int[] reverseSortedPositions) {
				for (int position : reverseSortedPositions) {
					mWeatherService.Locations.remove(mWeatherService.Locations.get(position));
				}
				UpdateLocationsData();
				SetSummaryData(mLocationsData);
			}
		});
		mSummary.setOnTouchListener(touchListener);
		// Setting this scroll listener is required to ensure that during
		// ListView scrolling,
		// we don't look for swipes.
		//mSummary.setOnScrollListener(touchListener.makeScrollListener());

		/*
		// 下拉刷新。
		mSummary.setOverScrollMode(ListView.OVER_SCROLL_ALWAYS);
		mSummary.SetOnOverScrollListener(new OverScrollListView.OnOverScrollListener() {
			
			int mAccumulatedDeltaY = 0;
			
			@Override
			public void OnOverScrolling(int deltaY) {
				// TODO Auto-generated method stub
				
				mAccumulatedDeltaY += deltaY;
				
			}
			
			@Override
			public void OnOverScrolled() {
				// TODO Auto-generated method stub

				if(mAccumulatedDeltaY > 64) {
					RefreshCurrentWeathers();
				}
				
				mAccumulatedDeltaY = 0;
				
			}
		});
		*/
		
		// 点击项目。
		mSummary.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				
				ShowLocationDetail(mWeatherService.Locations.get(position));
				CloseDrawer();	
			}
		});
		
		mAddLocation = (Button) findViewById(R.id.activity_weather_addLocation);
		mAddLocation.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				ShowAddLocationDialog();
			}
		});
		
		mTemperatureSensorListener = new SensorEventListener() {
			@Override
			public void onSensorChanged(SensorEvent event) {
				mCurrentTemperature.setText(event.values[0] + "°C");
			}
			
			@Override
			public void onAccuracyChanged(Sensor sensor, int accuracy) {
				// TODO Auto-generated method stub
				
			}
		};
		
		mHandler = new Handler();

		bindService(new Intent(this, WeatherService.class), mServiceConnection, BIND_AUTO_CREATE);
		
	}

	@Override
	protected void onPostCreate(Bundle savedInstanceState) {
		super.onPostCreate(savedInstanceState);
		mDrawerToggle.syncState();
		
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		
		SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
		mTemperatureSensor = sensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
		
		if(mTemperatureSensor != null) {
			sensorManager.registerListener(mTemperatureSensorListener, mTemperatureSensor, SensorManager.SENSOR_DELAY_NORMAL);
		}
		else {
			mCurrentTemperature.setText("温度传感器不可用。");
		}
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.weather, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		if (mDrawerToggle.onOptionsItemSelected(item)) {
			return true;
		}
		else {
			switch(item.getItemId()) {
			case R.id.activity_weather_refresh:
				RefreshDetailedWeathers();
				return true;
			case R.id.activity_weather_refreshAll:
				RefreshWeathers();
				return true;
			default:
				return super.onOptionsItemSelected(item);
			}
		}
	}

	@Override
	protected void onPause() {
		SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
		
		if(mTemperatureSensor != null) {
			sensorManager.unregisterListener(mTemperatureSensorListener, mTemperatureSensor);
		}
		
		SaveLocations();
		
		super.onPause();
	}

	@Override
	protected void onDestroy() {
		
		unbindService(mServiceConnection);
		
		super.onDestroy();
	}

	public void LoadLocations() {
		mWeatherService.LoadLocations();
		UpdateLocationsData();
		SetSummaryData(mLocationsData);
	}

	public void SaveLocations() {
		mWeatherService.SaveLocations();
	}

	public void AddLocation(String locationName) {
		mWeatherService.AddLocation(locationName);
		
		UpdateLocationsData();
		SetSummaryData(mLocationsData);
	}

	public void UpdateCurrentLocation() {
		
		Toast.makeText(WeatherActivity.this, "正在请求您的位置！", Toast.LENGTH_SHORT).show();

		final LocationClient locationClient = ((Application) getApplicationContext()).LocationClient;

		locationClient.registerLocationListener(new BDLocationListener() {

			@Override
			public void onReceivePoi(BDLocation location) {

			}

			@Override
			public void onReceiveLocation(BDLocation location) {

				StringBuilder sb = new StringBuilder();

				sb.append("时间：").append(location.getTime()).append("\n");
				sb.append("坐标：").append(location.getLongitude() + ", " + location.getLatitude()).append("\n");
				sb.append("省份：").append(location.getProvince()).append("\n");
				sb.append("城市：").append(location.getCity()).append("\n");
				sb.append("地址：").append(location.getAddrStr()).append("\n");

				String city = location.getCity();
				if (city != null) {
					mWeatherService.CurrentLocation.Name = location.getCity();
				}

				Toast.makeText(WeatherActivity.this, sb.toString(), Toast.LENGTH_SHORT).show();

				RefreshCurrentWeathers();
				
				locationClient.unRegisterLocationListener(this);
				
				locationClient.stop();

			}
		});

		locationClient.start();

	}
	
	public void UpdateLocationsData() {

		mLocationsData.clear();

		int size = mWeatherService.Locations.size();
		for (int i = 0; i < size; i++) {

			Location location = mWeatherService.Locations.get(i);

			HashMap<String, Object> map = new HashMap<String, Object>();
			if (location.Weathers[0] != null) {
				Weather currentWeather = location.Weathers[0];
				map.put(KEY_WEATHER_ICON, currentWeather.WeatherIconURI);
				map.put(KEY_LOCAITON_NAME, location.Name);
				map.put(KEY_WEATHER, currentWeather.Weather);
				map.put(KEY_TEMPERATURE, currentWeather.TemperatureCelsius);
			} else {
				map.put(KEY_WEATHER_ICON, R.drawable.ic_launcher);
				map.put(KEY_LOCAITON_NAME, location.Name);
				map.put(KEY_WEATHER, "-");
				map.put(KEY_TEMPERATURE, "-");
			}
			mLocationsData.add(map);

		}

	}

	/*
	 * public void UpdateCurrentWeather() {
	 * 
	 * (new UpdateCurrentWeatherAsyncTask()).execute();
	 * 
	 * }
	 */

	public void RefreshCurrentWeathers() {

		if(!mWeatherService.IsRefreshing) {
			(new RefreshWeathersAsyncTask()).execute(new Location[] { mWeatherService.CurrentLocation });
		}
		else {
			Toast.makeText(this, "正在刷新，请稍后再试。", Toast.LENGTH_SHORT).show();
		}

	}
	
	public void RefreshDetailedWeathers() {

		if(!mWeatherService.IsRefreshing) {
			(new RefreshWeathersAsyncTask()).execute(new Location[] { mDetailedLocation });
		}
		else {
			Toast.makeText(this, "正在刷新，请稍后再试。", Toast.LENGTH_SHORT).show();
		}

	}
	
	public void RefreshWeathers() {

		if(!mWeatherService.IsRefreshing) {
			Location[] ls = new Location[1];
			(new RefreshWeathersAsyncTask()).execute(mWeatherService.Locations.toArray(ls));
		}
		else {
			Toast.makeText(this, "正在刷新，请稍后再试。", Toast.LENGTH_SHORT).show();
		}

	}
	
	public void SetSummaryData(ArrayList<HashMap<String, Object>> locationsData) {

		String[] from = new String[] { KEY_WEATHER_ICON, KEY_LOCAITON_NAME, KEY_WEATHER, KEY_TEMPERATURE };

		int[] to = new int[] { R.id.summary_list_item_weatherIcon, R.id.summary_list_item_locationName, R.id.summary_list_item_weather, R.id.summary_list_item_temperature };

		SimpleAdapter simpleAdapter = new SimpleAdapter(this, locationsData, R.layout.summary_list_item, from, to);

		mSummary.setAdapter(simpleAdapter);

	}
	
	public void SetDetailData(ArrayList<HashMap<String, Object>> weathers) {

		String[] from = new String[] { KEY_WEATHER_ICON, KEY_WEATHER, KEY_TEMPERATURE };

		int[] to = new int[] { R.id.detail_list_item_weatherIcon, R.id.detail_list_item_weather, R.id.detail_list_item_temperature };

		SimpleAdapter simpleAdapter = new SimpleAdapter(this, weathers, R.layout.detail_list_item, from, to);

		mDetail.setAdapter(simpleAdapter);

	}
	
	public void OpenDrawer() {
		mDrawerLayout.openDrawer(GravityCompat.START);
		mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);
	}
	
	public void CloseDrawer() {
		mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
		mDrawerLayout.closeDrawer(GravityCompat.START);
	}
	
	public void ShowLocationDetail(Location location) {
		
		mLocationName.setText(location.Name);
		
		ArrayList<HashMap<String, Object>> weathers = new ArrayList<HashMap<String,Object>>();
		
		for(int i = 0; i < location.Weathers.length; i++) {
			
			Weather weather = location.Weathers[i];
			
			if(weather != null) {
				HashMap<String, Object> map = new HashMap<String, Object>();
				map.put(KEY_WEATHER_ICON, weather.WeatherIconURI);
				map.put(KEY_WEATHER, weather.Weather);
				map.put(KEY_TEMPERATURE, weather.TemperatureCelsius);
				
				weathers.add(map);
			}
			
		}
		
		SetDetailData(weathers);
		
		mDetailedLocation = location;
		
	}
	
	public void ShowAddLocationDialog() {
		(new AddLocationDialog()).show(getSupportFragmentManager(), "AddLocationDialog");
	}

}
